package com.dtp.core.notify.filter;

import com.dtp.core.support.ExecutorWrapper;
import com.dtp.common.entity.NotifyItem;
import com.dtp.common.pattern.filter.Invoker;
import com.dtp.core.context.BaseNotifyCtx;
import com.dtp.core.notify.alarm.AlarmLimiter;
import com.dtp.core.notify.manager.AlarmManager;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.collections.CollectionUtils;

import java.util.Objects;

/**
 * 基础报警过滤器
 *
 * @author yanhom
 * @since 1.0.8
 *
 * @remark muse
 **/
@Slf4j
public class AlarmBaseFilter implements NotifyFilter {

    private static final Object SEND_LOCK = new Object();

    @Override
    public void doFilter(BaseNotifyCtx context, Invoker<BaseNotifyCtx> nextInvoker) {
        val executorWrapper = context.getExecutorWrapper();
        val notifyItem = context.getNotifyItem();

        // 消息是否满足发送条件，不满足则直接返回
        if (Objects.isNull(notifyItem) || !satisfyBaseCondition(notifyItem, executorWrapper)) return;

        // 是否触发了报警限制，如果触发了，则本次不发送警告
        boolean ifAlarm = AlarmLimiter.ifAlarm(executorWrapper.getThreadPoolName(), notifyItem.getType());
        if (!ifAlarm) return;

        // 是否超过了设置的阈值，如果超过了，则本次不发送警告
        if (!AlarmManager.checkThreshold(executorWrapper, context.getNotifyItemEnum(), notifyItem)) return;

        // 将某个线程池的某个通知类型维护到警报限流器中
        synchronized (SEND_LOCK) {
            // 如果不满足报警条件，则不执行报警操作，直接返回
            ifAlarm = AlarmLimiter.ifAlarm(executorWrapper.getThreadPoolName(), notifyItem.getType());
            if (!ifAlarm) return;

            // 将某个线程池的某个通知类型维护到警报限流器中
            AlarmLimiter.putVal(executorWrapper.getThreadPoolName(), notifyItem.getType());
        }

        nextInvoker.invoke(context); // 请求调用链中的下一个Inovker实现类
    }

    /** 是否满足通知条件 */
    private boolean satisfyBaseCondition(NotifyItem notifyItem, ExecutorWrapper executor) {
        return executor.isNotifyEnabled()                                   // 线程池开启通知
                && notifyItem.isEnabled()                                   // 通知配置项是开启状态
                && CollectionUtils.isNotEmpty(notifyItem.getPlatformIds()); // 存在PlatformIds
    }

    @Override
    public int getOrder() {return 0;}
}
